﻿using IcicleFramework.Components.Actions.ActionEffects;
using IcicleFramework.Entities;

namespace IcicleFramework.Components.Actions
{
    public interface IAction : IXmlBuildable, ISubComponent
    {
        /// <summary>
        /// Gets the <see cref="ActionState"/> describing the current state of this <see cref="IAction"/>.
        /// </summary>
        ActionState State { get; }

        /// <summary>
        /// Gets or sets the <see cref="IActionEffect"/> that can attach itself to a target and perform special actions.
        /// </summary>
        IActionEffect ActionEffect { get; set; }
        
        /// <summary>
        /// Gets the <see cref="IActionComponent"/> that controls this <see cref="IAction"/>.
        /// </summary>
        IActionComponent Parent { get; set; }

        /// <summary>
        /// Gets or sets the <see cref="IGameObject"/> target for this <see cref="IAction"/>.
        /// </summary>
        IGameObject Target { get; set; }

        /// <summary>
        /// Gets whether or not this <see cref="IAction"/> is performing its action.
        /// </summary>
        bool PerformingActions { get; }

        /// <summary>
        /// Gets whether or not this <see cref="IAction"/> is continually performing actions.
        /// </summary>
        bool ContinuousActions { get; }

        /// <summary>
        /// Gets the number of actions that were performed since this <see cref="IAction"/> last started performing actions.
        /// </summary>
        int NumActionsPerformedSinceStarted { get; }

        /// <summary>
        /// An event that is fired when this <see cref="IAction"/> begins performing actions.
        /// </summary>
        event OnStartedPerformingActionsHandler OnStartedPerformingActions;

        /// <summary>
        /// An event that is fired when this <see cref="IAction"/> performs an action.
        /// </summary>
        event OnStartedPerformingActionsHandler OnPerformingAction;

        /// <summary>
        /// An event that is fired when this <see cref="IAction"/> stops performing actions.
        /// </summary>
        event OnStoppedPerformingActionsHandler OnStoppedPerformingActions;

        /// <summary>
        /// Executes this <see cref="IAction"/>'s action on the given <see cref="IGameObject"/> target.
        /// </summary>
        /// <param name="target">The <see cref="IGameObject"/> target for this action.</param>
        /// <param name="data">An optional <see cref="IActionData"/> providing any necessary data for this <see cref="IAction"/></param>
        /// <param name="continuous">An optional boolean - if true, then this <see cref="IAction"/> will execute actions continuously. If false, only a single action is executed.</param>
        void Execute(IGameObject target, IActionData data = null, bool continuous = false);

        /// <summary>
        /// Stops execution of this <see cref="IAction"/>.
        /// </summary>
        void Stop();

        /// <summary>
        /// Provides a deep-copy of this <see cref="IAction"/>
        /// </summary>
        /// <returns>A deep-copied clone of this <see cref="IAction"/></returns>
        IAction DeepClone();
    }
}
